home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
CRS
/
crs20.d81
/
fracland.sfx
/
fractal.hrland.c
< prev
Wrap
Text File
|
1990-02-12
|
10KB
|
353 lines
/* ╨ROGRAM: FRACTAL.HRLAND ┴UTHOR: ╨AUL ╫. ├ARLSON
*
* ╘HIS PROGRAM PLOTS RANDOM FRACTAL LANDSCAPES IN HIRES
* MODE ON THE ├64. ├OMPILED WITH THE ╨OWER ├ COMPILER.
*/
#DEFINE ╠┴╬─ 1
#DEFINE ╫┴╘┼╥ 2
#DEFINE ╙╦┘ 3
/* ╟LOBAL VARIABLES - ONLY MASK, COLOR, AND ODD ARE USED OUTSIDE OF
* THE MAIN FUNCTION. ╘HE OTHERS ARE DECLARED GLOBAL FOR MEMORY
* ALLOCATION PURPOSES ONLY.
*/
UNSIGNED
MASK[320]; /* MASK FOR HIDDEN LINE REMOVAL */
INT
H[65][65]; /* HEIGHT OR ELEVATION ABOVE SEA LEVEL */
UNSIGNED
COLOR, /* PIXEL COLOR */
FMAX, /* MAX. ELEVATION */
SEED, /* SEED FOR RANDOM NUMBER GENERATOR */
X; /* DISTANCE ALONG X-AXIS */
INT
Z, /* ELEVATION ABOVE SEA LEVEL */
ZP, /* PREVIOUS ELEVATION ABOVE SEA LEVEL */
ODD, /* 1 FOR ODD NUMBERED CROSS-SECTIONS, 0 FOR EVEN */
FIRST; /* 1 IF FIRST POINT ON CROSS-SECTION, ELSE 0 */
/*============ ╞UNCTION: MAIN =====================================*/
MAIN()
█
UNSIGNED I1, I2, J1, J2, /* INDEXES FOR NODES AT CORNERS */
DELTA, /* DIFFERENCE IN INDEXES FOR NODES AT ENDS OF SIDE */
IM, JM, /* INDEXES OF NODE AT MIDPOINT OF SIDE */
I, /* CROSS-SECTION NUMBER */
J, /* SEGMENT NUMBER */
BX, BY, /* X,Y COORDINATES OF BEGINNING OF LINE SEGMENT */
EX, EY, /* X,Y COORDINATES OF END OF LINE SEGMENT */
N; /* LOOP COUNTER */
CHAR *VPTR, ASEED[6], C, GETKEY();
HIGHMEM(35840);
TEXTMODE(11, 1, 11);
PRINTF("%C%C%C", 147, 14, 5);
PRINTF("\N ╞RACTAL ╠ANDSCAPES\N");
PRINTF(" ┴UTHOR: ╨AUL ├ARLSON\N\N\N");
PRINTF("╔T TAKES ABOUT ONE MINUTE TO COMPUTE THE");
PRINTF("ELEVATIONS FOR EACH LANDSCAPE. ╫HEN A ");
PRINTF("LANDSCAPE IS COMPLETE, PRESS ╥┼╘╒╥╬.\N\N\N\N");
PRINTF(" ╨RESS ANY KEY TO BEGIN...");
GETKEY();
/*------- MAIN LOOP - LOOP UNTIL A ZERO SEED IS ENTERED --------*/
WHILE (1)
█
TEXTMODE(11, 1, 11);
PRINTF("%C%C%C", 147, 14, 5);
PRINTF("┼NTER SEED FOR RANDOM NUMBER GENERATOR\N");
PRINTF(" (1 TO 32767, OR 0 TO QUIT): ");
GETS(ASEED);
SEED = ATOI(ASEED);
IF (!SEED) BREAK;
SRANDOM(SEED);
PRINTF("\N├OMPUTING ELEVATIONS...");
FOR (N = 0; N < 320; N++) MASK[N] = 200;
/*------------- COMPUTE HEIGHTS AT ALL NODES -----------------*/
FMAX = 0;
FOR (DELTA = 64; DELTA >= 2; DELTA >>= 1)
█ J1 = 0;
FOR (J2 = DELTA; J2 <= 64; J1 += DELTA, J2 += DELTA)
█ I1 = 0;
JM = (J1 + J2)>>1; /* GET MIDPOINT J INDEX */
FOR (I2 = DELTA; I2 <= 64; I1 += DELTA, I2 += DELTA)
█ IM = (I1 + I2)>>1; /* GET MIDPOINT I INDEX */
H[J1][IM] = (H[J1][I1] + H[J1][I2]) / 2 + RANDM(DELTA);
H[J2][IM] = (H[J2][I1] + H[J2][I2]) / 2 + RANDM(DELTA);
IF (I1) /* IF NOT THE BOTTOM EDGE OF PLOT... */
H[JM][I1] = (H[J1][I1] + H[J2][I1]) / 2 + RANDM(DELTA);
H[JM][I2] = (H[J1][I2] + H[J2][I2]) / 2 + RANDM(DELTA);
IF (RANDOM() & 1) /* PICK DIAGONAL RANDOMLY */
H[JM][IM] = (H[J1][I1] + H[J2][I2] + 3 * RANDM(DELTA))/2;
ELSE
H[JM][IM] = (H[J2][I1] + H[J1][I2] + 3 * RANDM(DELTA))/2;
▌
▌
▌
/*---------------- SMOOTH THE HEIGHTS -------------------------*/
FOR (I = 0; I <= 64; I++)
FOR (J = 1; J < 64; J++)
H[J][I] = (H[J-1][I] + H[J][I] + H[J+1][I]) / 3;
/*------------------- DRAW BORDER -----------------------------*/
HIRES(11, 1, 11);
FOR (N = 0; N < 317; N++)
█ PIXEL(N, 0);
PIXEL(N, 198);
▌
FOR (N = 0; N < 199; N++)
█ PIXEL(0, N);
PIXEL(316, N);
▌
/*------ DISPLAY THE PLOT, REMOVING HIDDEN LINES --------------*/
FOR (I = 0; I <= 64; I++)
█ ODD = 0;
FOR (N = 0; N < 2; N++)
█ ZP = 0;
FIRST = 1;
IF (I == 64 && ODD) BREAK;
FOR (J = 0; J < 64; J ++)
█ X = 5 * J;
/*-------- INTERPOLATE TO GET HEIGHTS ON ODD SECTIONS -----
AND ADJUST IF GOING INTO OR COMING OUT OF
THE WATER. */
IF (J && J < 63 && I < 64)
█ IF (ODD) /* THEN INTERPOLATE */
█ IF (H[J-1][I] + H[J-1][I+1] > 0 && /* ENTERING */
H[J][I] + H[J][I+1] < 0) /* WATER */
X += 5 * (H[J][I] + H[J][I+1]) /
(H[J-1][I] + H[J-1][I+1] -
H[J][I] - H[J][I+1]);
ELSE
IF (H[J+1][I] + H[J+1][I+1] > 0 && /* LEAVING */
H[J][I] + H[J][I+1] < 0) /* WATER */
X += 5 * (H[J][I] + H[J][I+1]) /
(H[J][I] + H[J][I+1] -
H[J+1][I] - H[J+1][I+1]);
▌
ELSE /* DON'T INTERPOLATE */
█ IF (H[J-1][I] > 0 && H[J][I] < 0) /* ENTERING WATER */
X += 5 * H[J][I] / (H[J-1][I] - H[J][I]);
ELSE
IF (H[J+1][I] > 0 && H[J][I] < 0) /* LEAVING WATER */
X += 5 * H[J][I] / (H[J][I] - H[J+1][I]);
▌
▌
IF (ODD) Z = (H[J][I] + H[J][I+1]) / 2;
ELSE Z = H[J][I];
/*------- SET ALL NEGATIVE HEIGHTS TO WATER LEVEL -------*/
IF (Z < 0) Z = 0;
IF ((Z + ZP) == 0) COLOR = ╫┴╘┼╥;
ELSE COLOR = ╠┴╬─;
ZP = Z;
/*-------- COMPUTE THE COORDINATES AND PLOT THE -----------
LINE SEGMENT. */
EX = X;
EY = I + I + ODD + Z + 1;
IF (EY > FMAX) FMAX = EY;
IF (FIRST)
█ BX = EX = 1;
BY = EY;
FIRST = 0;
▌
IF (I ▀▀ ODD) PLOT(BX, BY, EX, EY);
BX = EX;
BY = EY;
▌
IF (ODD) ODD = 0;
ELSE ODD = 1;
▌
▌
/*------ FILL IN SKY AND THEN WAIT UNTIL ╥┼╘╒╥╬ IS HIT ---------*/
/* REMOVE HIDDEN LINES UNTIL ABOVE MOUNTAINS */
COLOR = ╙╦┘;
FOR (BY = 129; BY <= FMAX; BY ++) PLOT(1, BY, 315, BY);
/* NOW USE A FAST FILL */
FOR (BY = 198 - FMAX; BY; BY--)
█ I = BY & 0XFFF8;
VPTR = 40960 + (I << 5) + (I << 3) + (BY & 7);
FOR (X = 0; X < 39; VPTR += 8, X++) *VPTR = 255;
*VPTR = 248;
▌
WHILE ((C = GETKEY()) != 13);
▌
TEXTMODE(6, 14, 14);
PRINTF("%C%C%C", 147, 142, 154);
▌
/* ╞UNCTION: PLOT
*
* ╘HIS FUNCTION PLOTS THE LINE SEGMENT(S) WITH HIDDEN LINE REMOVAL
*/
PLOT(X1, Y1, X2, Y2)
UNSIGNED X1, Y1, X2, Y2;
█
INT DX, DY, EI, ED, ER, IX, IY, T, SWAP;
/*-------------- COMPUTE DELTA X AND DELTA Y --------------------*/
Y1 = 199 - Y1;
Y2 = 199 - Y2;
DX = X2 - X1;
IF (Y1 < Y2)
█ T = Y2;
Y2 = Y1;
Y1 = T;
T = X2;
X2 = X1;
X1 = T;
IX = -1;
▌
ELSE IX = 1;
DY = Y1 - Y2;
IY = -1;
SWAP = 0;
IF (DY > DX)
█ SWAP = 1;
T = DX;
DX = DY;
DY = T;
▌
/*------------------ COMPUTE ERROR TERMS ------------------------*/
EI = DY<<1;
ED = (DY - DX)<<1;
ER = (DY<<1) - DX;
/*------------------ PLOT THE LINE SEGMENT(S) -------------------*/
FOR (DX++; DX; DX--)
█ IF (Y1 < MASK[X1])
█ MASK[X1] = Y1;
SWITCH (COLOR)
█ CASE 1: IF (!ODD) PIXEL(X1, Y1);
BREAK;
CASE 2: IF ((X1 & 1) == (Y1 & 1)) PIXEL(X1, Y1);
BREAK;
CASE 3: PIXEL(X1, Y1);
BREAK;
▌
▌
/*--------- UPDATE THE X OR Y COORDINATE AND ERROR TERM -------*/
IF (SWAP) Y1 += IY;
ELSE X1 += IX;
IF (ER < 0) ER += EI;
ELSE
█ ER += ED;
IF (SWAP) X1 += IX;
ELSE Y1 += IY;
▌
▌
▌
/* ╞UNCTION: RANDM
*
* ╘HIS FUNCTION RETURNS A RANDOM INTEGER IN THE RANGE
* -DELTA+1 TO DELTA-1 INCLUSIVE.
*/
RANDM(DELTA)
INT DELTA;
█
INT N;
N = RANDOM() & (DELTA - 1);
RETURN(((RANDOM() & 255) < 127) ? -N : N);
▌
/* ╞UNCTION: HIRES
*
* ╘HIS VERSION OF HIRES PUTS THE BITMAP UNDER ┬┴╙╔├ ╥╧═
* TO GET ENOUGH MEMORY AND STILL HAVE THE PROGRAM ╠╧┴─
* AND ╙┴╓┼ AS A ┬┴╙╔├ PROGRAM.
*/
HIRES(BACKGRND, FOREGRND, BORDER)
CHAR BACKGRND, FOREGRND, BORDER;
█
CHAR COLOR, *PTR;
PTR = 53280;
*PTR = BORDER;
COLOR = (FOREGRND << 4) ▀ BACKGRND;
FOR (PTR = 40960; PTR < 48960; PTR++) *PTR = 0;
FOR (PTR = 35840; PTR < 36840; PTR++) *PTR = COLOR;
PTR = 1;
*PTR = *PTR & 254;
PTR = 56576;
*PTR = (*PTR & 252) ▀ 1;
PTR = 53272;
*PTR = (*PTR & 15) ▀ 48;
*PTR = (*PTR & 240) ▀ 8;
PTR = 53265;
*PTR ▀= 32;
PTR = 648;
*PTR = 140;
▌
/* ╞UNCTION: TEXTMODE
*/
TEXTMODE(BACKGRND, FOREGRND, BORDER)
CHAR BACKGRND, FOREGRND, BORDER;
█
CHAR *PTR;
PTR = 1;
*PTR = *PTR ▀ 1;
PTR = 53280;
*PTR++ = BORDER;
*PTR = BACKGRND;
FOR (PTR = 1024; PTR < 2024; PTR++) *PTR = 32;
FOR (PTR = 55296; PTR < 56296; PTR++) *PTR = FOREGRND;
PTR = 56576;
*PTR = (*PTR & 252) ▀ 3;
PTR = 53265;
*PTR &= 223;
PTR = 53272;
*PTR = (*PTR & 15) ▀ 16;
*PTR = (*PTR & 240) ▀ 4;
PTR = 648;
*PTR = 4;
▌
/* ╞UNCTION: PIXEL
*
* ╙ETS THE PIXEL AT X,Y
*/
PIXEL(X, Y)
UNSIGNED X, Y;
█
CHAR *V;
UNSIGNED TMP;
STATIC CHAR BITVALS[] = █ 128, 64, 32, 16, 8, 4, 2, 1 ▌;
TMP = Y & 0XFFF8;
V = 40960 + (TMP << 5) + (TMP << 3) + ((Y & 7) ▀ (X & 0XFFF8));
*V ▀= BITVALS[X & 7];
▌
/* ╞UNCTION: GETKEY
*
* ╫AITS FOR AND RETURNS A KEYPRESS.
*/
CHAR GETKEY()
█
CHAR A, X, Y;
A = 0;
WHILE (A == 0) SYS(0XF13E, &A, &X, &Y);
RETURN A;
▌